﻿using System;

using NHibernate;
using NHibernate.Criterion;

namespace Progresoft.Scheduler.RemoteInterface.Api
{
	static class CriteriaUtility
	{
		public static ICriteria SetPadingAndOrder(this ICriteria criteria,
			String sortingExpression, String defaultSorting, int pageSize, int startIndex)
		{
			criteria.SetOrder(sortingExpression, defaultSorting);
			criteria.SetPaging(pageSize, startIndex);
			return criteria;
		}

		public static ICriteria SetPaging(this ICriteria criteria, int pageSize, int startIndex)
		{
			if (pageSize > 0 && startIndex >= 0)
			{
				criteria.SetFirstResult(startIndex).SetMaxResults(pageSize);
			}
			return criteria;
		}

		private static void parseSortDescriptor(String sortDescriptor, out String property, out Boolean asceding)
		{
			int idx = sortDescriptor.ToLower().IndexOf(" desc");
			asceding = idx < 0;
			property = asceding ? sortDescriptor.Trim() : sortDescriptor.Substring(0, idx).Trim();
		}

		private static char[] sortExpressionSeparator = new char[] { ',' };

		public static ICriteria SetOrder(this ICriteria criteria, String sortingExpression, String defaultSorting)
		{
			Boolean addDefaultSorting = false, defaultAsceding = false;
			String defaultProperty = null;
			if (!String.IsNullOrEmpty(defaultSorting))
			{
				addDefaultSorting = true;
				parseSortDescriptor(defaultSorting, out defaultProperty, out defaultAsceding);
			}
			if (!String.IsNullOrEmpty(sortingExpression))
			{
				String[] sortDescriptors = sortingExpression.Split(sortExpressionSeparator);
				Boolean asceding;
				String property;
				foreach (string sortDescriptor in sortDescriptors)
				{
					parseSortDescriptor(sortDescriptor, out property, out asceding);
					if (property.Length > 0)
					{
						if (addDefaultSorting && property.Equals(defaultProperty))
						{
							addDefaultSorting = false;
						}
						criteria.AddOrder(new Order(property, asceding));
					}
				}
			}
			if (addDefaultSorting)
			{
				criteria.AddOrder(new Order(defaultProperty, defaultAsceding));
			}
			return criteria;
		}
	}
}
